import os
os.environ["QT_API"] = "pyqt5"
import matplotlib
matplotlib.use("Qt5Agg")

import sys
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QPushButton
from PyQt5.QtCore import QThread, pyqtSignal
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Fcq
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as Ntq
import numpy as np

class TimeCanvas:
    """
    定义时域图
    """
    def __init__(self):
        # 窗口
        self.widget = QWidget()
        # 按钮
        self.button = QPushButton("&Start")
        # 图控件
        self.fig = Figure(figsize=(8, 10), dpi=110, facecolor='white')
        self.canvas = Fcq(self.fig)
        self.axes = self.fig.add_subplot(111)
        # 工具栏控件
        self.toolbar = Ntq(self.canvas, self.widget)
        # 布局
        self.layout = QVBoxLayout()
        # 将控件的设置都放在init_TimeCanvas中
        self.more_settings()
        # 实例化线程
        self.work = Worker()
        self.button.clicked.connect(self.execute)

    def more_settings(self):
        # 设置窗口大小
        self.widget.resize(1000, 800)
        # 设置图控件
        self.fig.subplots_adjust(top=0.915, bottom=0.155, left=0.11, right=0.955, hspace=0.2, wspace=0.2)
        self.axes.set_title('Time Diagram', pad=0, loc='center', size=20, color='red')
        self.axes.set_xlabel('Time(s)', fontsize='x-large', color='red')
        self.axes.set_ylabel('Amplitude(V)', fontsize='x-large', color='red')
        self.axes.grid(ls='--')  # 生成网格
        self.canvas.draw()
        # 工具栏控件
        self.toolbar.update()
        # 将按钮、图、工具栏加入布局
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.button)
        # 设置布局
        self.layout.setContentsMargins(0, 0, 0, 0)
        # 将布局加入窗口
        self.widget.setLayout(self.layout)
        # 显示窗口
        self.widget.show()

    def execute(self):
        self.work.start()
        self.work.signal.connect(self.display)

    def display(self, x, y):
        # 不清空画布绘图
        # 获取当前画布x轴与y轴的范围
        x_min1, x_max1 = self.axes.get_xlim()
        y_min1, y_max1 = self.axes.get_ylim()
        # 获取x与y的范围
        x_min2, x_max2 = np.min(x), np.max(x)
        y_min2, y_max2 = np.min(y), np.max(y)
        # 比较后得出x轴与y轴应设置的范围
        x_min, x_max = min(x_min1, x_min2), max(x_max1, x_max2)
        y_min, y_max = min(y_min1, y_min2), max(y_max1, y_max2)
        # 设置轴的范围
        self.axes.set_xlim(x_min, x_max)
        self.axes.set_ylim(y_min, y_max)
        # 绘图
        self.axes.scatter(x, y)
        # 显示
        self.canvas.draw()


class Worker(QThread):
    signal = pyqtSignal(np.ndarray, np.ndarray)

    def __init__(self, parent=None):
        super(Worker, self).__init__(parent)
        self.working = True

    def __del__(self):
        self.working = False
        self.wait()

    def run(self):
        t = np.arange(0,0.2,0.1)
        while self.working == True:
            # 绘图
            self.signal.emit(t, np.sin(t))
            t += 0.2
            # 线程休眠1秒
            self.sleep(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    my_gui = TimeCanvas()
    sys.exit(app.exec_())
